/**
 * @file      : list.h
 * @brief     : 链表头文件
 * @author    : huenrong (huenrong1028@gmail.com)
 * @date      : 2020-09-06 15:04:51
 *
 * @copyright : Copyright (c) 2020  胡恩荣
 *
 */

#ifndef __LIST_H
#define __LIST_H

#include <stdint.h>
#include <pthread.h>

// 链表存储数据定义
struct list_data
{
    uint8_t id;
    uint32_t time;
};

// 链表存储数据类型定义
typedef struct list_data element_type;

// 链表节点定义
struct list_node
{
    element_type data;
    struct list_node *next;
};

/**
 * @brief  初始化链表(创建一个头节点)
 * @param  list: 输出参数, 创建的链表
 * @param  list_mutex: 输出参数, 链表互斥锁
 * @return 成功: 0
 *         失败: -1
 */
int init_list(struct list_node *list,
              pthread_mutex_t *list_mutex);

/**
 * @brief  在链表头部插入数据
 * @param  list_mutex : 输出参数, 链表互斥锁
 * @param  list       : 输出参数, 需要插入数据的链表
 * @param  insert_data: 输入参数, 待插入数据
 * @return 成功: 0
 *         失败: -1
 */
int insert_head_list(pthread_mutex_t *list_mutex,
                     struct list_node *list,
                     const element_type insert_data);

/**
 * @brief  在链表尾部插入数据
 * @param  list_mutex : 输出参数, 链表互斥锁
 * @param  list       : 输入参数, 需要插入数据的链表
 * @param  insert_data: 输入参数, 待插入数据
 * @return 成功: 0
 *         失败: -1
 */
int insert_tail_list(pthread_mutex_t *list_mutex,
                     const struct list_node *list,
                     const element_type insert_data);

/**
 * @brief  查找指定数据的节点(查找到第一个就返回)
 * @param  list_mutex: 输出参数, 链表互斥锁
 * @param  list      : 输入参数, 待查找的链表
 * @param  node_data : 输入参数, 待查找的节点数据
 * @return 成功: 查找到的节点信息
 *         失败: NULL
 */
struct list_node *find_node_list(pthread_mutex_t *list_mutex,
                                 const struct list_node *list,
                                 const element_type node_data);

/**
 * @brief  查找指定数据的前一个节点(查找到第一个就返回)
 * @param  list_mutex: 输出参数, 链表互斥锁
 * @param  list      : 输入参数, 待查找的链表
 * @param  node_data : 输入参数, 待查找的节点数据
 * @return 成功: 查找到的节点信息
 *         失败: NULL
 */
struct list_node *find_previous_node_list(pthread_mutex_t *list_mutex,
                                          const struct list_node *list,
                                          const element_type node_data);

/**
 * @brief  从链表中删除指定数据节点(只删除符合要求的第一个节点)
 * @param  list_mutex: 输出参数, 链表互斥锁
 * @param  list      : 输入参数, 待删除节点的链表
 * @param  node_data : 输入参数, 待删除节点的数据
 */
void delete_node_list(pthread_mutex_t *list_mutex,
                      const struct list_node *list,
                      const element_type node_data);

/**
 * @brief  判断链表是否为空
 * @param  list_mutex: 输出参数, 链表互斥锁
 * @param  list: 输入参数, 待判断的链表
 * @return 链表为空: 0
 *         链表非空: -1
 */
int is_empty_list(pthread_mutex_t *list_mutex,
                  const struct list_node *list);

/**
 * @brief  获取链表长度(包括首节点)
 * @param  list_mutex: 输出参数, 链表互斥锁
 * @param  list      : 输入参数, 待判断的链表
 * @return 链表长度
 */
int get_list_len(pthread_mutex_t *list_mutex,
                 const struct list_node *list);

/**
 * @brief  删除链表(头节点也会删除)
 * @param  list_mutex: 输出参数, 链表互斥锁
 * @param  list      : 输出参数, 待删除的链表
 */
void delete_list(pthread_mutex_t *list_mutex,
                 struct list_node *list);

/**
 * @brief  遍历链表(需要根据实际情况修改)
 * @param  list_mutex: 输出参数, 链表互斥锁
 * @param  list      : 输入参数, 待遍历链表
 */
void traverse_list(pthread_mutex_t *list_mutex,
                   const struct list_node *list);

#endif /* __LIST_H */
